/**
 * Copyright 2014-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.webank.fiscobcoscanal1.manager;

import java.io.IOException;
import java.math.BigInteger;
import java.util.List;
import java.util.Optional;

import org.bcos.web3j.protocol.Web3j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.webank.fiscobcoscanal1.constant.TaskConstants;
import com.webank.fiscobcoscanal1.db.entity.BlockTaskPool;
import com.webank.fiscobcoscanal1.db.repository.BlockTaskPoolRepository;

import lombok.extern.slf4j.Slf4j;

/**
 * TransactionExportManager
 *
 * @Description: TransactionExportManager
 * @author maojiayu
 * @data Oct 29, 2019 4:50:49 PM
 *
 */
@Service
@Slf4j
public class TransactionPrepareManager {
    @Autowired
    private Web3j web3j;
    @Autowired
    private BlockTaskPoolRepository blockTaskPoolRepository;
    @Autowired
    private TransactionExportManager transactionExportManager;

    public void execute() throws IOException {
        log.info("begin to prepare.");
        System.out.println(web3j == null);
        BigInteger n = web3j.ethBlockNumber().send().getBlockNumber();
        log.info("block number is {}", n);
        Optional<BlockTaskPool> o = blockTaskPoolRepository.findTopByOrderByBlockHeightDesc();
        List<BlockTaskPool> list = Lists.newArrayList();
        if (o.isPresent()) {
            log.info("database is not empty");
            BlockTaskPool blockTaskPool = o.get();
            if (blockTaskPool.getBlockHeight().compareTo(n) < 0) {
                export(blockTaskPool.getBlockHeight().add(BigInteger.ONE), n);
            }
        } else {
            log.info("database is empty");
            export(BigInteger.ZERO, n);
        }
    }

    public void export(BigInteger start, BigInteger end) throws IOException {
        for (BigInteger i = BigInteger.ZERO; i.compareTo(end) < 0; i
                .add(BigInteger.valueOf(TaskConstants.BATCH_NUMBER))) {
            log.info("Begin to prepare task from {} to {}", i,
                    end.min(i.add(BigInteger.valueOf(TaskConstants.BATCH_NUMBER))));
            transactionExportManager.export(prepare(i, end.min(i.add(BigInteger.valueOf(TaskConstants.BATCH_NUMBER)))));
        }
    }

    public List<BlockTaskPool> prepare(BigInteger start, BigInteger end) {
        log.info("Begin to prepare from {} to {}.", start, end);
        BigInteger tmp = start;
        List<BlockTaskPool> list = Lists.newArrayList();
        while (tmp.compareTo(end) <= 0) {
            BlockTaskPool pool = new BlockTaskPool();
            pool.setBlockHeight(tmp);
            list.add(pool);
            tmp = tmp.add(BigInteger.ONE);
        }
        blockTaskPoolRepository.saveAll(list);
        return list;
    }

}
